import Router from "koa-router";
import Koa, { Context } from "koa";
import fs from "fs";
import path from "path";
import logger from './logUtils'
import { getConfig } from "./readYaml";
class loaderRouter {
  app!: Koa; // 定义app的类型
  static loaderRouter: loaderRouter = new loaderRouter();
  init(app: Koa) {
    this.app = app; // 初始化app
    const {server:{port,rootPath,firstRouter}} = getConfig(process.cwd() + '/src/conf/config.yaml'); // 读取配置文件
    this.listen(port); // 监听端口
    // 初始化配置文件信息
    const rootConfig = {
      rootPath,
      firstRouter
    }
    this.loadRouterWrapper(rootConfig); // 加载路由
  }
  listen(port:number) {
    this.app.listen(port);
    logger.info(`正在运行,端口: ${port} `);
  }
  loadRouterWrapper(routerConfig: any) {
    // 获取一级路由
    const rootRouter = this.getRootRouter(routerConfig.firstRouter)
    // 获取二级路由目录的绝对路径的数组
    const filesPath = this.getAbsPath(routerConfig.rootPath);
    const fileRouterPath = this.getAbsPathFile(filesPath); // 加载所有路由文件的绝对路径
    this.loadAllRouter(fileRouterPath); // 加载所有路由
    this.app.context.rootRouter = rootRouter;  // 将根路由保存到app中（装饰器中使用)
    this.app.use(rootRouter.routes()); // 注册根路由
  }

  // 加载所有路由
  async loadAllRouter(paths: string[]) {
    for (let path of paths) {
      // 引入二级路由
      (await import(path)) as { default: Router };
    }
  }

  // 获取一级路由方法 (实例化路由方法)
  getRootRouter(firstPath:string) {
    const router = new Router();
    router.prefix(firstPath);
    return router;
  }
  // 加载所有路由文件数组
  getrouterFiles(dir: string) {
    const files = fs.readdirSync(dir); // 获取该目录下所有的文件名
    return files;
  }
  // 加载所有路由文件的绝对路径
  getAbsPath(routerPath:string) {
    const dir = path.join(process.cwd(), routerPath); // 获取目录地址
    const files = this.getrouterFiles(dir); // 获取文件名
    const allPath: string[] = []; // 所有路由文件的绝对路径
    for (let file of files) {
      // 拼接为绝对路径
      const fullFilePath = `${dir}/${file}`;
      allPath.push(fullFilePath);
    }

    return allPath
  }
  // 获取目录下的所有文件
  getAbsPathFile(dirs: string[]) {
    const allPath: string[] = []; // 所有路由文件的绝对路径
    for (let dir of dirs) {
      const file = this.getrouterFiles(dir)
      if (file.length === 0) continue;
      // 拼接为绝对路径
      const fullFilePath = `${dir}/${file}`;
      allPath.push(fullFilePath);
    }
    return allPath;
    
  }
}
export default loaderRouter.loaderRouter;